/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.genitus.drum.conf

import org.rogach.scallop.ScallopConf

/**
  * Buffer configuration.
  *
  * @author gwjiang (gwjiang@iflytek.com), 2016/8/19.
  */
trait BuffConf extends ScallopConf {
  /** buffer size. */
  lazy val buffSize = opt[Int]("buff_size",
    descr = "log buffer size",
    default = Some(1024 * 64),
    validate = (x: Int) => x > 1 && Integer.bitCount(x) == 1,
    required = false,
    noshort = true)

  /** buffer workers. */
  lazy val buffWokers = opt[Int]("buff_workers",
    descr = "log buffer handlers",
    default = Some(1),
    required = false,
    noshort = true)

  /** buffer wait strategy. */
  lazy val buffWaitStrategy = opt[String]("buff_wait_strategy",
    descr = "buffer wait strategy",
    default = Some(BuffType.SLEEPING),
    validate = Set(BuffType.SLEEPING, BuffType.BLOCKING, BuffType.YIELDING, BuffType.BUSYSPIN).contains,
    required = false,
    noshort = true)
}

/**
  * Buffer types.
  */
object BuffType {
  /**
    * This strategy is a good compromise between performance and CPU resource.
    * Latency spikes can occur after quiet periods.
    */
  final val SLEEPING = "sleeping"

  /**
    * This strategy can be used when throughput and low-latency
    * are not as important as CPU resource.
    */
  final val BLOCKING = "blocking"

  /**
    * This strategy is a good compromise between performance and CPU
    * resource without incurring significant latency spikes.
    */
  final val YIELDING = "yielding"

  /**
    * This strategy will use CPU resource to avoid syscalls which can introduce latency jitter.
    * It is best used when threads can be bound to specific CPU cores.
    */
  final val BUSYSPIN = "busyspin"
}
